package com.baomibing.flow.enginee;

import com.baomibing.core.exception.ServerRuntimeException;
import com.baomibing.flow.constant.ProcessTypeEnum;
import com.baomibing.flow.exception.FlowExceptionEnum;
import com.baomibing.flow.execute.Execution;
import com.baomibing.flow.model.WorkFlow;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

import java.util.List;

/**
 * TaskJoinProcess
 *
 * @author frog 2023/9/27 10:26
 * @version 1.0.0
 **/
@ToString
public class TaskJoinProcess extends Process{

    @Setter @Getter
    private List<SubProcess> processes;

    public TaskJoinProcess(WorkFlow flow) {
        super(flow);
        this.processType = ProcessTypeEnum.TASK_JOIN.name();
    }

    @Override
    public boolean beComplete() {

            for (SubProcess p : processes) {
                if (!p.beComplete()) {
                    return false;
                }
            }
            return true;

    }

    public void doVirtualReject() {
        for (SubProcess p : processes) {
            p.doVirtualReject();
        }
    }

    private boolean beNotComplete() {

        for (SubProcess p : processes) {
            if (p.beComplete()) {
                return false;
            }
        }
        return true;

    }

    @Override
    public boolean doProcess(Execution execution) {

       SubProcess subProcess =  fetchSubProcessByActor(execution.getActor());
       subProcess.doProcess(execution);

        return beComplete();
    }

    @Override
    public boolean doReject(Execution execution) {
        for (SubProcess subProcess : processes) {
            subProcess.doNestReject();
        }
        return beNotComplete();
    }

    public boolean doRejectIfMath(Execution execution) {
        SubProcess subProcess =  fetchSubProcessByActor(execution.getActor());
        return subProcess.doNestReject();
    }



    public SubProcess fetchSubProcessByActor(String actor) {
        for (SubProcess sub : processes) {
            if (sub.getActor().equals(actor)) {
                return sub;
            }
        }
        throw new ServerRuntimeException(FlowExceptionEnum.NOT_FOUND_THE_JOIN_PROCESS_OF_SUB_PROCESS_BY_ACTOR);
    }
}
